import java.util.Iterator;
import java.util.function.Consumer;

public class MyDoubleLists implements Iterable<Integer>{
    private final Node hand;
    private final Node tail;

    private static class Node {
        public Node prev;
        public Node next;
        public int value;

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.next = next;
            this.value = value;
        }
    }

    public MyDoubleLists() {
        hand = new Node(null,0,null);
        tail = new Node(hand,-1,null);
        hand.next = tail;
        tail.prev = hand;
    }

    //根据索引查找节点
    private Node findNode(int index) {
        int i = -1;
        for (Node p = hand; p !=tail ; p = p.next,i++){
            if (i == index) {
                return p;
            }
        }
        return null;
    }

    //根据索引插入节点
    public void insert(int index, int value) {
        Node p = findNode(index - 1);
        if (p == null){
            throw new RuntimeException("用索引访问失败");
        }
        Node prev = p;
        Node next = prev.next;
        Node insertNode = new Node(prev, value,next);
        prev.next = insertNode;
        next.prev = insertNode;
    }

    //头插节点
    public void addFirst(int value) {
        insert(0,value);
    }

    //尾插节点
    public void addLast(int value) {
        Node lats = tail;
        Node prev = lats.prev;
        Node addNode = new Node(prev,value,lats);
        prev.next = addNode;
        lats.prev = addNode;
    }

    //根据索引来删除节点
    public void remove(int index) {
        Node prev = findNode(index - 1);
        if (prev == null) {
            throw new RuntimeException("用索引来删除数据失败！");
        }
        Node remove = prev.next;
        if (remove == tail) {
            throw new RuntimeException("用索引来删除数据失败！");
        }
        Node next = remove.next;

        prev.next = next;
        next.prev = next;
    }

    //头删节点
    public void removeFirst() {
        remove(0);
    }

    //尾删节点
    public void removeLast() {
        Node remove = tail.prev;
        if (remove == hand){
            throw new RuntimeException();
        }
        Node prev = remove.prev;
        prev.next = tail;
        tail.prev = prev;
    }

    //根据索引来查询数据
    public int get(int index) {
        Node find = findNode(index);
        if (find == null){
            throw new RuntimeException("根据该索引找不到数据");
        }
        return find.value;
    }

    //实现迭代器循环
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node p = hand.next;
            @Override
            public boolean hasNext() {
                return p != tail;
            }

            @Override
            public Integer next() {
                int value = p.value;
                p = p.next;
                return value;
            }
        };

    }

    //使用递归来循环
    public void loop (Consumer<Integer> after,Consumer<Integer> before) {
        recursion(hand.next,before,after);
    }

    private void recursion (Node node,Consumer<Integer> before, Consumer<Integer> after) {
        if (node == tail) {
            return;
        }

        before.accept(node.value);
        recursion (node.next,before,  after);
        after.accept(node.value);
    }
}